package sk.bielyvlk.vlkgps;

import java.io.File;

import sk.bielyvlk.vlkgps.db.DbHelper;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;

public class VlkGps extends Activity implements LocationListener, Handler.Callback, ServiceConnection, SensorEventListener {
	public static final String TAG = "vlkGPS.VlkGps";
	
	private static final int EVENT_ON_2S = 1;
	private Handler handler;

	private LocationManager lm;
	
	VlkGpsService vlkGpsService = null;
	VlkGpsView vlkGpsView = null;
	
	private SensorManager sensorManager;
	
	public static final String DB_DIR = "/sdcard/vlkgps";

	public static void prepareDirectory() throws Exception {
		File dir = new File(DB_DIR);
		if (!dir.isDirectory()) dir.mkdir();
		if (!dir.isDirectory()) throw new Exception("can't create working dir on sdcard");
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(TAG, "************************");
		Log.d(TAG, "onCreate");
		
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		
		setContentView(R.layout.main);
		vlkGpsView = (VlkGpsView)findViewById(R.id.vlkGpsView);

		handler = new Handler(this);

		Intent serviceIntent = new Intent(VlkGps.this, VlkGpsService.class);
		startService(serviceIntent);
		bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);
		lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
	}
	
	@Override
	public void onStart() {
		super.onStart();
		Log.d(TAG, "onStart");
	}
	
	@Override
	public void onRestart() {
		super.onRestart();
		Log.d(TAG, "onRestart");
	}
	
	@Override
	public void onResume() {
		super.onResume();
		Log.d(TAG, "onResume");
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
		vlkGpsView.setActualLocation(lm.getLastKnownLocation(LocationManager.GPS_PROVIDER));
		sensorManager = (SensorManager)this.getSystemService(Context.SENSOR_SERVICE);
		sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
	}
	
	@Override
	public void onPause() {
		super.onPause();
		Log.d(TAG, "onPause");
		lm.removeUpdates(this);
		sensorManager.unregisterListener(this);
	}
	
	@Override
	public void onStop() {
		super.onStop();
		Log.d(TAG, "onStop");
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestroy");
		handler.removeMessages(EVENT_ON_2S);
		if (vlkGpsService != null) { 
			if (vlkGpsService.isRecording()) {
				Log.d(TAG, "unbinding...");
				unbindService(this);
			} else {
				Log.d(TAG, "stopping service...");
				unbindService(this);
				stopService(new Intent(VlkGps.this, VlkGpsService.class));
			}
			vlkGpsService = null;
		}
	}
	
	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		Log.d(TAG, "onServiceConnected");
		vlkGpsService = ((VlkGpsService.LocalBinder)service).getService();
		try {
			Cursor c = vlkGpsService.getDbHelper().getReadableDatabase().rawQuery("SELECT name, symbol, lon, lat, maxzoom FROM waypoints", null);
			c.moveToFirst();
			do {
				vlkGpsView.addWaypoint(new WayPoint((double)c.getLong(2) / DbHelper.DB_DEGREES_MULT, (double)c.getLong(3) / DbHelper.DB_DEGREES_MULT, c.getString(0), c.getString(1), (float)c.getLong(4)));
			} while (c.moveToNext());
			c.close();
		} catch (Exception e) {
			Log.e(TAG, e.toString());
		}
	}
	@Override
	public void onServiceDisconnected(ComponentName name) {
		Log.d(TAG, "onServiceDisconnected");
		vlkGpsService = null;
	}

	private static final int MENU_MY_LOCATION = Menu.FIRST;
	private static final int MENU_ADD_WAYPOINT = Menu.FIRST + 1;
	private static final int MENU_RECORD = Menu.FIRST + 2;
	private static final int MENU_CONFIGURE = Menu.FIRST + 3;
	private static final int MENU_WAYPOINTS = Menu.FIRST + 4;
	private static final int MENU_TRACKS = Menu.FIRST + 5;
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, MENU_MY_LOCATION, Menu.NONE, R.string.menuMyLocation);
		menu.add(0, MENU_ADD_WAYPOINT, Menu.NONE, R.string.menuAddWaypoint);
		if (vlkGpsService != null) menu.add(0, MENU_RECORD, Menu.NONE, vlkGpsService.isRecording() ? R.string.menuStopRecord : R.string.menuStartRecord);
		menu.add(0, MENU_WAYPOINTS, Menu.NONE, R.string.menuWaypoints);
		menu.add(0, MENU_TRACKS, Menu.NONE, R.string.menuTracks);
		menu.add(0, MENU_CONFIGURE, Menu.NONE, R.string.menuConfigure);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case MENU_MY_LOCATION:
				vlkGpsView.follow();
				vlkGpsView.setActualLocation(lm.getLastKnownLocation(LocationManager.GPS_PROVIDER));
				return true;
			case MENU_ADD_WAYPOINT:
				if (vlkGpsService == null) return true;
				vlkGpsService.getDbHelper().insertWaypoint("", "", "", vlkGpsView.getActualLocation());
				vlkGpsView.addWaypoint(new WayPoint(vlkGpsView.getActualLocation().getLongitude(), vlkGpsView.getActualLocation().getLatitude(), "", "", 0));
				return true;
			case MENU_RECORD:
				if (vlkGpsService == null) return true; 
				if (vlkGpsService.isRecording()) {
					vlkGpsService.recordStop();
					item.setTitle(R.string.menuStartRecord);
				} else {
					vlkGpsService.recordStart("");
					if (vlkGpsService.isRecording()) item.setTitle(R.string.menuStopRecord);
				}
				return true;
			case MENU_WAYPOINTS: {
				Intent myIntent = new Intent(vlkGpsView.getContext(), WayPointsList.class);
		                startActivityForResult(myIntent, 0);
		                return true;
			}
			case MENU_TRACKS: {
				Intent myIntent = new Intent(vlkGpsView.getContext(), TracksList.class);
		                startActivityForResult(myIntent, 0);
		                return true;
			}
			case MENU_CONFIGURE:
				return true;
		}
		return false;
	}

	@Override
	public boolean handleMessage(Message msg) {
		switch (msg.what) {
			case EVENT_ON_2S:
				handler.removeMessages(EVENT_ON_2S);
				handler.sendMessageDelayed(handler.obtainMessage(EVENT_ON_2S), 2000);
				break;
			default:
				break;
		}
		return true;
	}

	@Override
	public void onLocationChanged(Location location) {
		vlkGpsView.setActualLocation(location);
	}

	@Override
	public void onProviderDisabled(String arg0) {}

	@Override
	public void onProviderEnabled(String arg0) {}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {}

	@Override
	public void onSensorChanged(SensorEvent event) {
		vlkGpsView.setCompass(event.values[0]);
	}

}

